﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.CApAPPTranslationLimitWallManipulator
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System;
using System.Drawing;
using System.Windows.Forms;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands;

public class CApAPPTranslationLimitWallManipulator
{
  private TxManipulator m_manipulator;
  private Cursor m_previousCursor;
  private int m_pickedId;
  private Point m_startPoint;
  private TxTransformation m_viewerFrame;
  private double AxisdX;
  private double AxisdY;
  private double m_winWorldRatio;
  private double m_winViewRatio;
  private Point m_prevPoint;
  private TxVector m_deltaVec;

  public CApAPPTranslationLimitWallManipulator(
    CApAPPLimitsViewModel limitsViewModel,
    CApAPPTranslationLimitWall wall)
  {
    this.LimitsViewModel = limitsViewModel;
    this.m_pickedId = -1;
    this.m_deltaVec = (TxVector) null;
    this.Wall = wall;
    this.Axis = this.Wall.Axis;
    this.GhostLimits = new KiAppLimitsEx(this.LimitsViewModel.Limits);
    this.IsActivated = false;
    this.ComputeCurrentGraphicWallAbsolutePositionFromLimitValues();
    this.RegisterMouseEvents();
  }

  private CApAPPLimitsViewModel LimitsViewModel { get; set; }

  public bool IsActivated { get; private set; }

  private CApAPPTranslationLimitWall Wall { get; set; }

  private KiAppTranslationLimitWallAxis Axis { get; set; }

  public TxTransformation StartAbsoluteLocation => this.LimitsViewModel.ReferenceFrame;

  public KiAppLimitsEx GhostLimits { get; set; }

  public TxVector Direction { get; private set; }

  public TxVector CurrentGraphicLimitWallAbsolutePositionVect { get; private set; }

  public void ComputeCurrentGraphicWallAbsolutePositionFromLimitValues()
  {
    TxTransformation absoluteLocation = this.StartAbsoluteLocation;
    switch ((int) this.Axis)
    {
      case 0:
        this.Direction = new TxVector(-1.0, 0.0, 0.0);
        this.CurrentGraphicLimitWallAbsolutePositionVect = absoluteLocation.Transform(new TxVector(this.GhostLimits.TxMinValue, 0.0, 0.0));
        break;
      case 1:
        this.Direction = new TxVector(1.0, 0.0, 0.0);
        this.CurrentGraphicLimitWallAbsolutePositionVect = absoluteLocation.Transform(new TxVector(this.GhostLimits.TxMaxValue, 0.0, 0.0));
        break;
      case 2:
        this.Direction = new TxVector(0.0, -1.0, 0.0);
        this.CurrentGraphicLimitWallAbsolutePositionVect = absoluteLocation.Transform(new TxVector(0.0, this.GhostLimits.TyMinValue, 0.0));
        break;
      case 3:
        this.CurrentGraphicLimitWallAbsolutePositionVect = absoluteLocation.Transform(new TxVector(0.0, this.GhostLimits.TyMaxValue, 0.0));
        this.Direction = new TxVector(0.0, 1.0, 0.0);
        break;
      case 4:
        this.CurrentGraphicLimitWallAbsolutePositionVect = absoluteLocation.Transform(new TxVector(0.0, 0.0, this.GhostLimits.TzMinValue));
        this.Direction = new TxVector(0.0, 0.0, -1.0);
        break;
      case 5:
        this.Direction = new TxVector(0.0, 0.0, 1.0);
        this.CurrentGraphicLimitWallAbsolutePositionVect = absoluteLocation.Transform(new TxVector(0.0, 0.0, this.GhostLimits.TzMaxValue));
        break;
    }
  }

  public void CreateManipulator()
  {
    this.m_manipulator = TxApplication.ActiveDocument.PhysicalRoot.CreateManipulator(new TxManipulatorCreationData("Arrow", new TxTransformation()));
    TxObjectEx.SetVisibleOnly((ITxObject) this.m_manipulator);
  }

  public void Activate()
  {
    this.CreateManipulator();
    this.IsActivated = true;
  }

  public void Release()
  {
    this.UnregisterMouseEvents();
    this.DeleteManipulator();
    this.IsActivated = false;
  }

  protected virtual void DeleteManipulator()
  {
    if (!TxManipulator.op_Inequality(this.m_manipulator, (ITxObject) null))
      return;
    TxObjectEx.ForceDeletion((ITxObject) this.m_manipulator);
  }

  protected bool ValidPickObject(ITxObject pickObject)
  {
    return pickObject == this.m_manipulator || this.Wall.WallObject == pickObject;
  }

  private void RegisterMouseEvents()
  {
    TxGraphicViewer.MouseDown += new TxGraphicViewer_MouseEventHandler(this.TxGraphicViewerEx_MouseDown);
    TxGraphicViewer.MouseMove += new TxGraphicViewer_MouseEventHandler(this.TxGraphicViewerEx_MouseMove);
    TxGraphicViewer.MouseUp += new TxGraphicViewer_MouseEventHandler(this.TxGraphicViewerEx_MouseUp);
  }

  private void UnregisterMouseEvents()
  {
    TxGraphicViewer.MouseDown -= new TxGraphicViewer_MouseEventHandler(this.TxGraphicViewerEx_MouseDown);
    TxGraphicViewer.MouseMove -= new TxGraphicViewer_MouseEventHandler(this.TxGraphicViewerEx_MouseMove);
    TxGraphicViewer.MouseUp -= new TxGraphicViewer_MouseEventHandler(this.TxGraphicViewerEx_MouseUp);
  }

  private void TxGraphicViewerEx_MouseUp(object sender, TxGraphicViewer_MouseEventArgs e)
  {
    e.Handled = this.EndMouseDragging(e.Button, e.X, e.Y);
    this.RevertToPreviousCursor();
  }

  private void TxGraphicViewerEx_MouseMove(object sender, TxGraphicViewer_MouseEventArgs e)
  {
    e.Handled = this.MouseDragging(e.Button, e.X, e.Y);
  }

  private void TxGraphicViewerEx_MouseDown(object sender, TxGraphicViewer_MouseEventArgs e)
  {
    e.Handled = this.StartMouseDragging(e.Button, e.X, e.Y);
  }

  protected bool StartMouseDragging(MouseButtons button, int x, int y)
  {
    bool flag = false;
    TxGraphicPickInfoEx pickInfo = TxGraphicViewerEx.The.GetPickInfo(x, y);
    if (button == MouseButtons.Left && this.ValidPickObject(pickInfo.Object))
    {
      this.GhostLimits = new KiAppLimitsEx(this.LimitsViewModel.Limits);
      if (TxManipulator.op_Equality(this.m_manipulator, (ITxObject) null))
        this.Activate();
      else
        this.ComputeCurrentGraphicWallAbsolutePositionFromLimitValues();
      this.m_pickedId = pickInfo.EdgeId;
      flag = this.m_pickedId > -1;
      this.SetManipulateCursor();
      this.m_prevPoint = new Point(x, y);
      this.Initialize(this.m_prevPoint, pickInfo.Frame, 2);
    }
    return flag;
  }

  protected bool EndMouseDragging(MouseButtons button, int x, int y)
  {
    if (this.m_pickedId > -1)
    {
      this.m_pickedId = -1;
      this.RevertToPreviousCursor();
    }
    return false;
  }

  protected bool MouseDragging(MouseButtons button, int x, int y)
  {
    bool flag = false;
    if (button == MouseButtons.Left && this.m_pickedId > -1)
    {
      double dAxis1 = 0.0;
      Point curPoint = new Point(x, y);
      this.GetMovementDelta(curPoint, ref this.m_prevPoint, ref dAxis1);
      this.m_prevPoint = curPoint;
      if (dAxis1 != 0.0)
      {
        TxVector txVector = new TxVector(dAxis1 * Math.Abs(this.Direction.X), dAxis1 * Math.Abs(this.Direction.Y), dAxis1 * Math.Abs(this.Direction.Z));
        this.m_deltaVec = txVector;
        this.CurrentGraphicLimitWallAbsolutePositionVect = TxVector.op_Addition(this.CurrentGraphicLimitWallAbsolutePositionVect, txVector);
        this.UpdateWallLimits();
        TxApplication.RefreshDisplay();
      }
    }
    else if (this.m_pickedId > -1)
      this.EndMouseDragging(button, x, y);
    return flag;
  }

  protected void UpdateGhostLimits()
  {
    if (!TxVector.op_Inequality(this.m_deltaVec, (TxVector) null))
      return;
    switch ((int) this.Axis)
    {
      case 0:
        this.GhostLimits.TxMinValue += this.m_deltaVec.X;
        break;
      case 1:
        this.GhostLimits.TxMaxValue += this.m_deltaVec.X;
        break;
      case 2:
        this.GhostLimits.TyMinValue += this.m_deltaVec.Y;
        break;
      case 3:
        this.GhostLimits.TyMaxValue += this.m_deltaVec.Y;
        break;
      case 4:
        this.GhostLimits.TzMinValue += this.m_deltaVec.Z;
        break;
      case 5:
        this.GhostLimits.TzMaxValue += this.m_deltaVec.Z;
        break;
    }
  }

  protected void UpdateWallLimits()
  {
    this.UpdateGhostLimits();
    this.UpdateLimits();
  }

  protected void UpdateLimits()
  {
    switch ((int) this.Axis)
    {
      case 0:
        this.LimitsViewModel.TxMinValue = this.GhostLimits.TxMinValue > 0.0 ? 0.0 : this.GhostLimits.TxMinValue;
        break;
      case 1:
        this.LimitsViewModel.TxMaxValue = this.GhostLimits.TxMaxValue < 0.0 ? 0.0 : this.GhostLimits.TxMaxValue;
        break;
      case 2:
        this.LimitsViewModel.TyMinValue = this.GhostLimits.TyMinValue > 0.0 ? 0.0 : this.GhostLimits.TyMinValue;
        break;
      case 3:
        this.LimitsViewModel.TyMaxValue = this.GhostLimits.TyMaxValue < 0.0 ? 0.0 : this.GhostLimits.TyMaxValue;
        break;
      case 4:
        this.LimitsViewModel.TzMinValue = this.GhostLimits.TzMinValue > 0.0 ? 0.0 : this.GhostLimits.TzMinValue;
        break;
      case 5:
        this.LimitsViewModel.TzMaxValue = this.GhostLimits.TzMaxValue < 0.0 ? 0.0 : this.GhostLimits.TzMaxValue;
        break;
    }
    this.Wall.LimitsDidChanged();
  }

  public void Initialize(Point startPoint, TxTransformation refFrame, int activeAxis)
  {
    this.m_startPoint = startPoint;
    this.m_winViewRatio = (double) TxApplication.ViewersManager.GraphicViewer.ViewRectangle.Width / (double) ((TxViewer) TxApplication.ViewersManager.GraphicViewer).ContainerWindow.Bounds.Width;
    this.CalcRatio(refFrame);
  }

  public bool GetMovementDelta(Point curPoint, ref Point prevPoint, ref double dAxis1)
  {
    double num1 = (double) (curPoint.X - prevPoint.X);
    double num2 = (double) (prevPoint.Y - curPoint.Y);
    double num3 = (double) (curPoint.X - this.m_startPoint.X);
    double num4 = (double) (this.m_startPoint.Y - curPoint.Y);
    bool movementDelta = true;
    double num5 = this.AxisdX * num1 + this.AxisdY * num2;
    int num6 = num1 >= 0.0 ? 1 : -1;
    if (this.AxisdX < 0.0)
      num6 = -1 * num6;
    prevPoint.X = (int) ((double) prevPoint.X + (double) num6 * this.AxisdX * Math.Abs(num5));
    int num7 = num2 >= 0.0 ? -1 : 1;
    if (this.AxisdY < 0.0)
      num7 = -1 * num7;
    prevPoint.Y = (int) ((double) prevPoint.Y + (double) num7 * this.AxisdY * Math.Abs(num5));
    dAxis1 = this.m_winWorldRatio * num5;
    return movementDelta;
  }

  protected bool CalcRatio(TxTransformation refFrame)
  {
    this.m_viewerFrame = TxApplication.ViewersManager.GraphicViewer.ViewingMatrix;
    TxTransformation txTransformation = TxTransformation.op_Multiply(this.m_viewerFrame, refFrame);
    double num1 = txTransformation[0, 2];
    double num2 = txTransformation[1, 2];
    double num3 = txTransformation[2, 2];
    this.AxisdX = num1 / Math.Sqrt(num1 * num1 + num2 * num2);
    this.AxisdY = num2 / Math.Sqrt(num1 * num1 + num2 * num2);
    this.m_winWorldRatio = this.m_winViewRatio * Math.Sqrt((num1 * num1 + num2 * num2 + num3 * num3) / (num1 * num1 + num2 * num2));
    return true;
  }

  public void SetManipulateCursor()
  {
    if (this.m_previousCursor == (Cursor) null)
      this.m_previousCursor = TxGraphicViewerEx.The.Cursor;
    this.GetType();
    Cursor cursor = new Cursor(this.GetType(), "AutomaticPathPlanner.res.LimitManipulatorCursor.cur");
    if (!(cursor != (Cursor) null))
      return;
    TxGraphicViewerEx.The.Cursor = cursor;
    cursor.Dispose();
  }

  public void RevertToPreviousCursor()
  {
    TxGraphicViewerEx.The.Cursor = this.m_previousCursor;
    if (!(this.m_previousCursor != (Cursor) null))
      return;
    this.m_previousCursor.Dispose();
    this.m_previousCursor = (Cursor) null;
  }
}
